package com.test.mongo;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientURI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import java.util.ArrayList;
import java.util.List;

/**
 * 快照处理 mongo
 * SnapshotMongoTemplateConfig
 * @author zhanglong
 * @date 2020年3月13日
 */
@Configuration
public class SnapshotMongoTemplateConfig extends AbstractMongoConfiguration{
	
	@Autowired
	MongoOptionProperties mongoOptionProperties;
	
	@Value("${spring.data.mongodb.snapshot.uri}")
	private String uri;

	@Override
	@Primary
	@Bean(name = "snapshotMongoTemplate") 
	public MongoTemplate mongoTemplate() throws Exception {
		return new MongoTemplate(dbFactory(),this.mappingMongoConverter());
	}
	
	public MongoDbFactory dbFactory() throws Exception {
		MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
		builder.minConnectionsPerHost(mongoOptionProperties.getMinConnectionPerHost())
				.connectionsPerHost(mongoOptionProperties.getMaxConnectionPerHost())
				.threadsAllowedToBlockForConnectionMultiplier(
						mongoOptionProperties.getThreadsAllowedToBlockForConnectionMultiplier())
				.serverSelectionTimeout(mongoOptionProperties.getServerSelectionTimeout())
				.maxWaitTime(mongoOptionProperties.getMaxWaitTime())
				.maxConnectionIdleTime(mongoOptionProperties.getMaxConnectionIdleTime())
				.maxConnectionLifeTime(mongoOptionProperties.getMaxConnectionLifeTime())
				.connectTimeout(mongoOptionProperties.getConnectTimeout())
				.socketTimeout(mongoOptionProperties.getSocketTimeout())
				//.socketKeepAlive(mongoOptionProperties.getSocketKeepAlive())
				.sslEnabled(mongoOptionProperties.getSslEnabled())
				.sslInvalidHostNameAllowed(mongoOptionProperties.getSslInvalidHostNameAllowed())
				.alwaysUseMBeans(mongoOptionProperties.getAlwaysUseMBeans())
				.heartbeatFrequency(mongoOptionProperties.getHeartbeatFrequency())
				.minConnectionsPerHost(mongoOptionProperties.getMinConnectionPerHost())
				.heartbeatConnectTimeout(mongoOptionProperties.getHeartbeatConnectTimeout())
				.heartbeatSocketTimeout(mongoOptionProperties.getSocketTimeout())
				.localThreshold(mongoOptionProperties.getLocalThreshold()).build();
		MongoClient mongoClient = new MongoClient(mongoClient().getAddress(), builder.build());
		return new SimpleMongoDbFactory(mongoClient, getDatabaseName());
	}
	
    @Override
	public MappingMongoConverter mappingMongoConverter() throws Exception {
        DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(this.dbFactory());
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, this.mongoMappingContext());
        List<Object> list = new ArrayList<>();
        list.add(new BigDecimalToDecimal128Converter());//自定义的类型转换器
        list.add(new Decimal128ToBigDecimalConverter());//自定义的类型转换器
        converter.setCustomConversions(new MongoCustomConversions(list));
        return converter;
    }
	
    @Override
	public MongoMappingContext mongoMappingContext() {
        MongoMappingContext mappingContext = new MongoMappingContext();
        return mappingContext;
    }

	@Override
	public MongoClient mongoClient() {
		MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
        return mongoClient;
	}

	@Override
	protected String getDatabaseName() {
		return uri.substring(uri.lastIndexOf("/") + 1, uri.length());
	}
}
